package com.gzhryc.common.event;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.quartz.CronScheduleBuilder;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

//Cron表达式范例：
//每隔5秒执行一次：*/5 * * * * ?
//每隔1分钟执行一次：0 */1 * * * ?
//每天23点执行一次：0 0 23 * * ?
//每天凌晨1点执行一次：0 0 1 * * ?
//每月1号凌晨1点执行一次：0 0 1 1 * ?
//每月最后一天23点执行一次：0 0 23 L * ?
//每周星期天凌晨1点实行一次：0 0 1 ? * L
//在26分、29分、33分执行一次：0 26,29,33 * * * ?
//每天的0点、13点、18点、21点都执行一次：0 0 0,13,18,21 * * ?

/**
 * Quartz定时器服务
 * @author 张浩
 *
 */
public class QuartzServer {
	
	static Scheduler scheduler;

	public static synchronized boolean start(){
		try{
			if(scheduler == null){
				Properties props = new Properties();
				props.setProperty("org.terracotta.quartz.skipUpdateCheck", "true");
				StdSchedulerFactory factory = new StdSchedulerFactory();
				scheduler = factory.getScheduler();
			}
			if(!scheduler.isStarted()){
				scheduler.start();
			}
			return true;
		}catch (SchedulerException se) {
            se.printStackTrace();
        }
		return false;
	}
	
	/**
	 * 按时间定时执行任务
	 * @param cronExpression
	 * @param job
	 * @return
	 */
	public static boolean delayedRunJob(String cronExpression,Class<? extends Job> job,boolean startNow){
		return delayedRunJob(cronExpression,job,startNow,null);
	}
	
	/**
	 * 按时间定时执行任务
	 * @param cronExpression
	 * @param job
	 * @return
	 */
	public static boolean delayedRunJob(String cronExpression,Class<? extends Job> job){
		return delayedRunJob(cronExpression,job,false,null);
	}
	
	/**
	 * 按时间定时执行任务
	 * @param cronExpression
	 * @param job
	 * @return
	 */
	public static boolean delayedRunJob(String cronExpression,Class<? extends Job> job,Map<String,Object> values){
		return delayedRunJob(cronExpression,job,false,values);
	}
	
	/**
	 * 按时间定时执行任务
	 * @param cronExpression
	 * @param job
	 * @return
	 */
	public static <T> boolean delayedRunJob(String cronExpression,Class<? extends Job> job, T obj){
		Map<String,Object> data = new HashMap<String,Object>();
		data.put(obj.getClass().getSimpleName(), obj);
		return delayedRunJob(cronExpression,job,false,data);
	}
	
	/**
	 * 按时间定时执行任务
	 * @param cronExpression
	 * @param job
	 * @return
	 */
	public static boolean delayedRunJob(String cronExpression,Class<? extends Job> job,boolean startNow,Map<String,Object> values){
		try{
			if(scheduler != null && scheduler.isStarted()) {
				JobDetail jobDetail = JobBuilder.newJob(job)
			            	.withIdentity(job.getSimpleName(), job.getPackage().getName())
			                .build();
				if(values != null){
					jobDetail.getJobDataMap().putAll(values);
				}
				
				CronScheduleBuilder csb = CronScheduleBuilder.cronSchedule(cronExpression);
				TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger()
		                 .withIdentity(job.getSimpleName(), job.getPackage().getName());
				
				Trigger trigger = triggerBuilder.withSchedule(csb).build();
				scheduler.scheduleJob(jobDetail, trigger);
				
				if(startNow){
					JobDetail simpleJobDetail = JobBuilder.newJob(job)
			            	.withIdentity(job.getSimpleName()+"_startNow", job.getPackage().getName())
			                .build();
					if(values != null){
						simpleJobDetail.getJobDataMap().putAll(values);
					}
					//简单触发器才能触发立刻执行
					SimpleTrigger simpleTrigger = TriggerBuilder.newTrigger()
			                 .withIdentity(job.getSimpleName()+"_startNow", job.getPackage().getName())
			                 .withSchedule(SimpleScheduleBuilder.simpleSchedule())
			                 .startNow().build();
					scheduler.scheduleJob(simpleJobDetail, simpleTrigger);
				}
				return true;
			}
		}catch (SchedulerException se) {
			se.printStackTrace();
		}
		return  false;
	}
	
	/**
	 * 根据秒数构建一个Cron表达式，最大支持小时级秒数
	 * @param seconds	秒数
	 * @return
	 */
	public static String buildCronExpression(Long seconds){
		if(seconds >= 3600){
			Long hours = seconds/3600;
			Long temp = seconds%3600;
			Long minutes = 0L;
			if(temp >= 60){
				minutes = temp/60;
				temp = temp%60;
			}
			return temp+" "+minutes+" */"+hours+" * * ?";
		}else if(seconds >= 60){
			Long minutes = seconds/60;
			Long temp = seconds%60;
			return temp+" */"+minutes+" * * * ?";
		}else {
			return "*/"+seconds+" * * * * ?";
		}
	}
	
 	public static void stop(){
		try {
			scheduler.shutdown(true);
		} catch (SchedulerException se) {
			se.printStackTrace();
		}
	}
	
}
